#region Imported Namespaces
using System;
using System.Collections.Specialized;
using System.Data;
using System.Web.UI.WebControls;

using PHSRAG.Insight21.Context;
using BO = PHSRAG.Insight21.BusinessObjects;
using DataAccess = PHSRAG.Utility.DataAccess;
using ICachePolicy = PHSRAG.Insight21.Policy.ICachePolicy;
using GenerateKey = PHSRAG.Insight21.BusinessObjects.ModuleKey;
#endregion

namespace PHSRAG.Insight21.SearchContext
{
	#region Class CommonSearchContext
	/// <summary>
	/// The CommonSearchContext class encapsulates the search context associated with the CommonSearch control. This
	/// context includes the PI/Lab/COS picker data and the state of any additional controls that may exist within the
	/// CommonSearch control.
	/// </summary>
	public class CommonSearchContext : SearchContext
	{
		#region Constants
		private static string CommonSearchContextKey = GenerateKey.MakeKey("commonSearchContext_0D1E0395-46CD-457d-B9E7-780F670D9AB7",GenerateKey.Common);
		#endregion

		#region Constructor
		/// <summary>
		/// Create an instance of the CommonSearchContext object and instantiate its data container.
		/// </summary>
		/// <param name="cachePolicy"></param>
		public CommonSearchContext(ICachePolicy cachePolicy) : base(cachePolicy)
		{
			DataContainer = new DataSet();
		}
		#endregion

		#region Class Properties
		/// <summary>
		/// Get the key to be used in all caching operations for this instance of the object.
		/// </summary>
		public static string CacheKey	{ get { return CommonSearchContextKey; } }

		/// <summary>
		/// Get the key to be used to access COS data.
		/// </summary>
		public static string COSPickerKey	{ get { return "COS"; } }

		/// <summary>
		/// Get the key to be used to access Lab data.
		/// </summary>
		public static string LabPickerKey	{ get { return "LAB"; } }

		/// <summary>
		/// Get the key to be used to access PI data.
		/// </summary>
		public static string PIPickerKey	{ get { return "PI"; } }
		#endregion

		#region Public Methods
		/// <summary>
		/// Return the data used to load the a picker control. The data is lazy-loaded into the data container.
		/// </summary>
		/// <param name="tableName">Name of the table in the data container to load into</param>
		/// <param name="loaderName">Name of the stored procedure which should be used to load the data</param>
		/// <returns>DataTable containing PI data</returns>
		public DataTable GetPickerData(string tableName, string loaderName)
		{
			DataTable table = DataContainer.Tables[tableName];
			if (table == null)
			{
				UserContext userContext = CachePolicy.GetCachedObject(UserContext.CacheKey) as UserContext;
				System.Diagnostics.Trace.Assert(userContext != null);

				table = DataContainer.Tables.Add(tableName);
				DataAccess.LoadDataTable(table, DataAccess.ConnectionString, loaderName,
					DataAccess.BuildSqlParameterArray("@domainUserID", SqlDbType.Int, userContext.DomainUserId));
			}
			return table;
		}

		/// <summary>
		/// Return the data used to load the a picker control. The data is lazy-loaded into the data container.
		/// </summary>
		/// <param name="tableName">Name of the table in the data container to load into</param>
		/// <param name="loaderName">Name of the stored procedure which should be used to load the data</param>
		/// <returns>DataTable containing PI data</returns>
		public DataTable GetPickerDataForOrgTree(string tableName, string loaderName)
		{
			DataTable table = null;
			string PreviousModuleKey = "PreviousModuleKey" ;
			string currentModule = (string)CachePolicy.GetCachedObject(CurrentModuleKey) ;

            /*Modified By: at098, 04/29/2008
             * Fix for TrackIt incident 8274
             * The complete module name is passed to the stored procedure
             */
            //string  moduleName = currentModule.Substring(0,1);

			if(CachePolicy.GetCachedObject(PreviousModuleKey) ==  null)
			{
				CachePolicy.Cache(PreviousModuleKey, currentModule);
			}

			if((string)CachePolicy.GetCachedObject(PreviousModuleKey) == (string)CachePolicy.GetCachedObject(CurrentModuleKey))
			{
			
			 table = DataContainer.Tables[tableName];
				if (table == null)
				{
					UserContext userContext = CachePolicy.GetCachedObject(UserContext.CacheKey) as UserContext;
					System.Diagnostics.Trace.Assert(userContext != null);

					table = DataContainer.Tables.Add(tableName);

					

					DataAccess.LoadDataTable(table, DataAccess.ConnectionString, loaderName,
						DataAccess.BuildSqlParameterArray("@domainUserID", SqlDbType.Int, userContext.DomainUserId, "@ModuleName" ,
                        SqlDbType.VarChar, currentModule.Trim().ToLower()));
				}
			}
			else
			{
				UserContext userContext = CachePolicy.GetCachedObject(UserContext.CacheKey) as UserContext;
				System.Diagnostics.Trace.Assert(userContext != null);
				if(!DataContainer.Tables.Contains(tableName))
				{
					table = DataContainer.Tables.Add(tableName);
				}
				else
				{
					table =  DataContainer.Tables[tableName];
					table.Rows.Clear();
				}

				DataAccess.LoadDataTable(table, DataAccess.ConnectionString, loaderName,
					DataAccess.BuildSqlParameterArray("@domainUserID", SqlDbType.Int, userContext.DomainUserId,"@ModuleName" ,
                    SqlDbType.VarChar, currentModule.Trim().ToLower()));

				CachePolicy.Cache(PreviousModuleKey, currentModule);
			
			}
			return table;
		}
		#endregion

		#region Class Methods
		/// <summary>
		/// Get the description associated with the current selection from a picker.
		/// </summary>
		/// <param name="pickerKey">Identifies the picker (PI/Lab/COS)</param>
		/// <param name="pickerID">Current selection in the picker</param>
		/// <returns>Description associated with the selection</returns>
		/// <remarks>
		/// <p>The description dependes on the picker key and is retrieved as follows:</p>
		/// <p>If the picker key is for PI:</p>
		/// <p>the picker ID is the primary key of the PI in the database. Get the full name of the PI from the database.</p>
		/// <p>If the picker key is for the COS:</p>
		/// <p>The picker ID is of the form "COS-description/COS-ID[|]+". Get the description from that string if only
		/// one COS is selected. If multiple selections exist, return the number of selections.</p>
		/// </remarks>
		public static string GetPickerDescription(string pickerKey, string pickerID)
		{
			pickerKey = pickerKey.ToUpper();

			if (pickerKey == CommonSearchContext.PIPickerKey)
				return (string)DataAccess.ExecuteScalar(DataAccess.ConnectionString, "GetPIFullName",
					DataAccess.BuildSqlParameterArray("@piID", SqlDbType.Int, pickerID));

			if (pickerKey == CommonSearchContext.COSPickerKey)
			{
				string[] elements = pickerID.Split('|');
				return (elements.Length == 1) ? elements[0].Split(':')[0] : string.Format("{0} selected", elements.Length);
			}

			if (pickerKey == CommonSearchContext.LabPickerKey)
				return (string)DataAccess.ExecuteScalar(DataAccess.ConnectionString, "GetLabName",
					DataAccess.BuildSqlParameterArray("@labID", SqlDbType.Int, pickerID));

			return "Unknown";
		}
		#endregion

		#region BusinessObject Methods
		/// <summary>
		/// Cache this instance of the CommonSearchContext object using the current cache policy.
		/// </summary>
		public override void Cache()
		{
			CachePolicy.Cache(CacheKey, this);
		}

		/// <summary>
		/// This method should NOT be invoked. It is there only because the CommonSearchContext derives from the
		/// BusinessObject.
		/// </summary>
		/// <param name="connectionString">Ignore this</param>
		/// <param name="args">Ignore this</param>
		public override void Load(string connectionString, params object[] args)
		{
			throw new Exception("The CommonSearchContext must not be loaded from the database");
		}

		/// <summary>
		/// Remove this instance of the CommonSearchContext object from the cache using the current cache policy.
		/// </summary>
		public override void UnCache()
		{
			CachePolicy.UnCache(CacheKey);
		}
		#endregion

		#region SearchContext Members
		/// <summary>
		/// Reset the internal search state while maintaining the PI search criteria if the user has access to only one PI. 
		/// </summary>
		public override void Reset(string pageName)
		{
			DataTable piDataTable = DataContainer.Tables["PI"];
			if (piDataTable != null && piDataTable.Rows.Count == 1) 
			{
				SearchCriteria searchCriteria = GetSearchCriteria(pageName);
				string currentPI =  searchCriteria[PIPickerKey];
				base.Reset(pageName);	// Don't do this BEFORE retrieving the PIPicker selection!
				if ( !String.IsNullOrEmpty(currentPI) )
				{
					SearchCriteria criteria = new SearchCriteria(((UserContext)CachePolicy.GetCachedObject(UserContext.CacheKey)).DomainUserId);
					criteria[PIPickerKey] = currentPI;
					criteria.Version = searchCriteria.Version; //don't want to lose the incremented version caused by reset.
					SetSearchCriteria(pageName, criteria);
				}
			}
			else
				base.Reset(pageName);
		}
		#endregion
	}
	#endregion
}

// --- EOF ---
